package nancal.mp.service

import io.kubernetes.client.openapi.ApiClient
import nancal.mp.db.mongo.JenkinsLanguageEnum
import nancal.mp.db.mongo.entity.sys.K8sSyncSetting
import nancal.mp.db.mongo.mor
import nancal.mp.db.mysql.dbr
import nancal.mp.db.redis.rer
import nancal.mp.imageNameVersion
import nancal.mp.mvc.ops.K8sSshSyncController
import nancal.mp.mvc.ops.K8sSshSyncController.Companion
import nbcp.base.comm.JsonResult
import nbcp.base.extend.HasValue
import nbcp.base.extend.Slice
import nbcp.base.model.SshClient
import nbcp.base.utils.SpringUtil
import nbcp.myoql.db.mongo.query
import org.slf4j.LoggerFactory
import org.springframework.scheduling.annotation.Async
import org.springframework.stereotype.Service
import kotlin.concurrent.thread


object SshSyncService {
    private var working = false;
    private val logger = LoggerFactory.getLogger(this::class.java)

    private val task = thread(start = true, isDaemon = true) {
        while (true) {
            Thread.sleep(1000)

            if (!working) {
                continue
            }

            try {
                var list = rer.sys.sshSync.getListString()

                if (!list.any()) {
                    working = false;
                    continue
                }


                var syncSetting = mor.sys.k8sSyncSetting.query()
                    .where { it.isActive mongoEquals true }
                    .toEntity()!!;


                workRec(syncSetting);

            } catch (e: Exception) {
                logger.error(e.message, e)
                working = false
            }
        }
    }

    fun work() {
        working = true;
    }


    fun workRec(syncSetting: K8sSyncSetting) {
        var list = rer.sys.sshSync.getListString()

        var first = list.firstOrNull();
        if (first.isNullOrBlank()) {
            working = false;
            return;
        }


        var sects = first.split(":")
        if (sects.size != 3) {
            logger.error("$first 不合法!")
            return
        }

        var type = sects[0];
        var ns = sects[1]
        var name = sects[2];

        doSyncYml(syncSetting, ns, name, if (type == "sync") false else true)

        rer.sys.sshSync.removeItems(first);

        workRec(syncSetting)
    }


    private val k8sDeployment by lazy {
        return@lazy SpringUtil.getBean<K8sDeploymentService>()
    }


    fun doSyncYml(
        syncSetting: K8sSyncSetting,
        namespace: String,
        name: String,
        syncAndDeploy: Boolean
    ): JsonResult {

        var testK8s = K8sBaseService.getK8sClient("")

        var deploymentResult = k8sDeployment.getDeploymentInfo(testK8s, namespace, name);
        if (deploymentResult.hasError) {
            return JsonResult.error(deploymentResult.msg)
        }

        var deployInfo = deploymentResult.data!!;
        var testFullImageVersion = deployInfo!!.fullImageVersion


        var language = deployInfo.language
        var svcName = name;
        var app = svcName;
        if (app.endsWith("-java")) {
            app = app.Slice(0, -5);
            language = JenkinsLanguageEnum.Java
        } else if (app.endsWith("-vue")) {
            app = app.Slice(0, -4);
            language = JenkinsLanguageEnum.Vue
        } else if (app.endsWith("-python")) {
            app = app.Slice(0, -7);
            language = JenkinsLanguageEnum.Python
        } else if (app.endsWith("-node")) {
            app = app.Slice(0, -5);
            language = JenkinsLanguageEnum.Node
        }


        if (language == null) {
            return JsonResult.error("语言信息丢失")
        }


//        var prodFullImageVersion = syncSetting.prodRegistry.host + "/" + testFullImageVersion.imageNameVersion
//            fullImageVersion = if (isProd) {} else {
//            syncSetting.uatServer.harborHost.AsString("reg2.huatuocloud.com")
//        } + "/" + fullImageVersion

        var varList = mutableMapOf<String, String>();
        varList.put("deployment", app)
        varList.put("imageVersion", testFullImageVersion.imageNameVersion.split(":").last())
        varList.put("language", language.toString().lowercase())
        varList.put("namespace", namespace)
//        varList.put("language", language.toString())
//        varList.put("svcName", svcName)
//        varList.put("imageVersion", imageNameVersion.AsString(fullImageVersion))


        var targetScript = syncSetting.testPushScript
        if (syncAndDeploy) {
            targetScript = syncSetting.prodDeployScript
            if (targetScript.isNullOrEmpty()) {
                return JsonResult.error("部署脚本不能为空!")
            }
        } else if (targetScript.isNullOrEmpty()) {
            return JsonResult.error("同步脚本不能为空!")
        }

//        var targetServer =  syncSetting.prodK8s
//            if (isProd) {} else {
//            syncSetting.uatServer
//        }


        var prodK8s = ApiClient();
        prodK8s.setApiKeyPrefix("Bearer")
        prodK8s.isVerifyingSsl = false;
        prodK8s.basePath = syncSetting.prodK8s.apiServerHost
        prodK8s.setApiKey(syncSetting.prodK8s.apiToken);


        var ssh = SshClient();
        ssh.host = syncSetting.testSsh.host;
        ssh.port = syncSetting.testSsh.sshPort;
        ssh.userName = syncSetting.testSsh.userName;
        ssh.password = syncSetting.testSsh.password;
        if (ssh.userName.isNullOrEmpty()) {
            return JsonResult.error("ssh 用户名不能为空");
        }

        //
        //如果第一次部署,则使用脚本,其它时候仅更新镜像.
        var prodService = k8sDeployment.getDeploymentInfo(prodK8s, namespace, name)

        varList.put("isNew", (prodService.data == null).toString().lowercase())
        var shellVar = varList.map { """export ${it.key}="${it.value}"; """ }.joinToString(" ")


//        if (prodService.data != null) {
//
//            //执行ssh脚本
//            var result = ssh.exec(shellVar + targetScript)
//
//            if (result.hasError) {
//                return JsonResult.error(result.msg)
//            }
//            if (result.data.HasValue) {
//                logger.warn(result.data);
//            }
//
//            return JsonResult()
//            //仅更新版本号
////            return k8sDeployment.setImageName(prodK8s, namespace, name, imageNameVersion.AsString(fullImageVersion))
//        }


        var result = ssh.exec(shellVar + targetScript)


        if (result.hasError) {
            return JsonResult.error(result.msg)
        }
        if (result.data.HasValue) {
            logger.warn(result.data);
        }

        return JsonResult()
    }
}